package com.dongdongshop.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dongdongshop.pojo.Cart;
import com.dongdongshop.pojo.TbItem;
import com.dongdongshop.pojo.TbOrderItem;
import com.dongdongshop.service.CartService;
import com.dongdongshop.service.ItemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import sun.util.resources.ga.LocaleNames_ga;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description
 * @ClassName CartServiceImpl
 * @Author RC
 * @date 2020.12.21 17:30
 */
@Component
@Service
public class CartServiceImpl implements CartService {
    @Reference(timeout = 10000,check = false)
    private ItemService itemService;
    @Autowired
    private RedisTemplate redisTemplate;
    private static final Logger logger = (Logger) LoggerFactory.getLogger(CartServiceImpl.class);


    @Override
    public List<Cart> addCart(List<Cart> cartList, Long itemId, Integer num) {

    //cartList 已经存在额购物车,itemId要添加的商品  num添加数量
    //第一种可能性:购物车没有数据,或者购物车中有但是没有在当前店铺(商家)买东西
    //第二种可能性:购物车有数据,也有这个店铺的东西,但是没有这件商品
    //第三种可能性:购物车有数据,也有店铺的东西,也买过这件商品


    //1.根据商品SKU ID查询SKU商品信息(itemId)
        TbItem item = itemService.findItemByItemId(itemId);
    //2.获取商家ID
        String sellerId = item.getSellerId();
    //3.根据商家ID判断购物车列表中(cartList)是否存在该商家的购物车
        Cart cart = getCartBySellerId(cartList, sellerId);
        //4.如果购物车列表中不存在该商家的购物车
        if(cart == null){
            //4.1 新建购物车对象
            cart = new Cart();
            //4.2 将新建的购物车对象添加到购物车列表
            cart.setSellerId(sellerId);
            cart.setSellerName(item.getSeller());
            List<TbOrderItem> orderItemList = new ArrayList<>();
            TbOrderItem orderItem = new TbOrderItem();
            orderItem.setNum(num);
            orderItem.setSellerId(sellerId);
            orderItem.setItemId(item.getId());
            orderItem.setPrice(item.getPrice());
            orderItem.setPicPath(item.getImage());
            orderItem.setGoodsId(item.getGoodsId());
            orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));
            orderItem.setTitle(item.getTitle());
            orderItemList.add(orderItem);
            cart.setOrderItemList(orderItemList);
            //将新创建的购物车放到购物车列表中
            cartList.add(cart);
        }else {
            //5.如果购物车列表中存在该商家的购物车(也就是sellerId不为null)
            List<TbOrderItem> orderItemList = cart.getOrderItemList();
            //6查询购物车明细列表中是否存在该商品
            TbOrderItem orderItem = getTbOrderItemByItemId(orderItemList, itemId);
            //6.1. 如果没有，新增购物车明细(list添加)
            if(orderItem == null){
                orderItem = new TbOrderItem();
                orderItem.setNum(num);
                orderItem.setSellerId(sellerId);
                orderItem.setItemId(item.getId());
                orderItem.setPrice(item.getPrice());
                orderItem.setPicPath(item.getImage());
                orderItem.setGoodsId(item.getGoodsId());
                orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));
                orderItem.setTitle(item.getTitle());
                orderItemList.add(orderItem);

            }else {
                //6.2. 如果有，在原购物车明细上添加数量，更改金额
                orderItem.setNum(orderItem.getNum() + num);
                orderItem.setTotalFee(new BigDecimal(orderItem.getNum() * orderItem.getPrice().doubleValue()));
                //如果当前商品购买数量小于或者等于 0 就说明没有买
                if(orderItem.getNum() <= 0){
                    orderItemList.remove(orderItem);
                }
                //如果删除掉商品之后的明细列表为空了,我们就认为当前店铺没有添加到购物车,
                if(orderItemList.size() <=0 ){
                    // 因此要将当前店铺的购物车从购物车列表中清除出去
                    cartList.remove(cart);
                }
            }
        }
        return cartList;
    }
    //根据商家ID判断购物车列表中(cartList)是否存在该商家的购物车
    private Cart getCartBySellerId(List<Cart> cartList, String sellerId) {
        for (Cart cart : cartList) {
            if (Objects.equals(cart.getSellerId(), sellerId)) {
                //有返回 cart
                return cart;
            }
        }
        //没有return null
        return null;
    }
    //根据itemId查询购物车明细列表中是否有这件商品
    private TbOrderItem getTbOrderItemByItemId(List<TbOrderItem> orderItemList,Long itemId){
        for (TbOrderItem orderItem : orderItemList) {
            if(Objects.equals(itemId,orderItem.getItemId())){
                //之前购物车中有这样的商品就返回
                return orderItem;
            }
        }
        //没有return null
        return null;
    }

    //从redis缓存获取购物车数据
    @Override
    public List<Cart> findCartListFormRedis(String username) {

        List<Cart> cartList =(List<Cart>) redisTemplate.boundHashOps("cartList").get(username);
        //判断从redis获取数据是否为空
        if(cartList == null){
            //为空就new 一个新的对象防止空指针异常
            cartList = new ArrayList<>();
        }
        return cartList;
    }
    //向redis缓存添加购物车数据  carList 大KEY  userId 小KEY
    @Override
    public void saveCartListToRedis(String userId, List<Cart> cartList) {

        redisTemplate.boundHashOps("cartList").put(userId,cartList);
    }
    //合并购物车 cookie 和redis
    @Override
    public List<Cart> margeCarListCookieAndRedis(List<Cart> cartListCookie, List<Cart> cartListFormRedis) {
        for (Cart cartCookie : cartListCookie) {
            //拿出cartCookie中每一条orderItem和现在要添加的组装在一起
            for (TbOrderItem orderItem : cartCookie.getOrderItemList()) {
                cartListFormRedis = addCart(cartListFormRedis, orderItem.getItemId(), orderItem.getNum());
            }
        }
        return cartListFormRedis;//追加好的
    }
}
